using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Soap;
using MsgLogic;
//using ClientLogic;
using System.Threading;
using System.Net.NetworkInformation;

namespace ServerLogicDll
{
    public class ConnectedClient
    {
        public event EventHandler<MsgArrivedEventArgs> MsgArrived;
        public event EventHandler<ClientDisonnectEventArgs> DisconnectClient;

        private TcpClient clientConnected;
        private Thread thread;
        private NetworkStream networkStream;
        private SoapFormatter soapFormatter;
        private string userName;
        private System.Timers.Timer t;

        public string UserName
        {
            get { return userName; }
            set { userName = value; }
        }
        public TcpClient ClientConnected
        {
            get { return clientConnected; }
            set { clientConnected = value; }
        }

        public void SendMsg(BaseMsg msg)
        {
            soapFormatter.Serialize(networkStream, msg);
        }

        public void GetMsg()
        {
            BaseMsg msg;
            while (true)
            {
                try
                {
                    msg = (BaseMsg)soapFormatter.Deserialize(networkStream);
                    OnMsgArrived(msg);
                }
                catch (Exception e)
                {
                    msg = new DisconnectMsg(userName);
                    //OnMsgArrived(msg);
                    OnClientDisconnect(userName);
                    
                }
                
            }

        }

        public void OnMsgArrived(BaseMsg msg)
        {
            if (MsgArrived != null)
                MsgArrived(this, new MsgArrivedEventArgs(msg));
        }

        public ConnectedClient(TcpClient clientConnected, Thread thread, NetworkStream networkStream, SoapFormatter soapFormatter, string userName)
        {
            this.clientConnected = clientConnected;
            this.thread = thread;
            this.networkStream = networkStream;
            this.soapFormatter = soapFormatter;
            this.userName = userName;
        }
       
        public ConnectedClient(TcpClient clientConnected)
        {
            this.clientConnected = clientConnected;
            this.soapFormatter = new SoapFormatter();
            this.networkStream = clientConnected.GetStream();

            //assign thread
            InitializeThread();
            thread.Start();

            //timer part
            t = new System.Timers.Timer(10000);
            t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed);
            t.Start();
        }

        void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            //Ping p = new Ping();
            //PingReply pr = p.Send(this.clientConnected.Connected
            if (!this.clientConnected.Connected)
            {
                OnClientDisconnect(userName);
                t.Stop();
            }
        }

        private void InitializeThread()
        {
            ThreadStart ts = new ThreadStart(GetMsg);
            thread = new Thread(ts);
            thread.IsBackground = true;
        }

        public void RemoveClient()
        {
            networkStream.Close();
            t.Stop();
            
            //OnClientDisconnect(userName);
        }
        public void OnClientDisconnect(string userName)
        {
            if (DisconnectClient != null)
                DisconnectClient(this, new ClientDisonnectEventArgs(userName));
        }
    }
}